package org.guohao.mockdata.utils;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.guohao.mockdata.constant.ManagerType;
import org.guohao.mockdata.entity.DBConnectEntity;
import org.guohao.mockdata.log.LoggingService;

class SQLiteManager implements DataManager {

  private Connection conn;
  private PreparedStatement statement;

  private static class Queries {

    private static final String[] CREATE_QUERIES = {
        "CREATE TABLE IF NOT EXISTS connect(name TEXT PRIMARY KEY, type TEXT NOT NULL, host TEXT NOT NULL, username TEXT NOT NULL, password TEXT NOT NULL)"
    };

    private static final String SAVE_CONNECT = "INSERT INTO connect(name, type, host,username,password) VALUES(?, ?, ?, ?,?)";
    private static final String SELECT_CONNECT = "SELECT * FROM connect";
  }

  public SQLiteManager() {
    try {
      String configPath = "data/";
      File configFolder = new File(configPath);
      if (!configFolder.exists()) {
        if (!configFolder.mkdirs()) {
          LoggingService.logSevere("Unable to create directory: " + configPath, null);
        }
      }
      conn = DriverManager.getConnection("jdbc:sqlite:data/db.sqlite");
      createDatabase();
    } catch (Exception E) {
      LoggingService.logSevere("Exception while initializing SQLiteManager.", E);
    }
  }

  /**
   * If not create and initialize the database with the necessary tables
   */
  private void createDatabase() throws SQLException {
    for (String query : Queries.CREATE_QUERIES) {
      statement = conn.prepareStatement(query);
      statement.execute();
    }
  }


  /**
   * Returns all saved connections
   */
  @Override
  public synchronized List<DBConnectEntity> getDBList() throws SQLException {
    List<DBConnectEntity> connectEntities = new ArrayList<>();
    // Loads the requests from the last x number of days, x being Settings.showHistoryRange
    statement = conn.prepareStatement(Queries.SELECT_CONNECT);
    ResultSet resultSet = statement.executeQuery();
    while (resultSet.next()) {
      connectEntities.add(new DBConnectEntity(resultSet.getString(1), resultSet.getString(2),
          resultSet.getString(3), resultSet.getString(4), resultSet.getString(5)));
    }
    return connectEntities;
  }

  @Override
  public ManagerType getIdentifier() {
    return ManagerType.SQLITE;
  }

  /**
   * Save connection
   */
  @Override
  public synchronized void saveConnectSetting(DBConnectEntity dbConnectInfo) throws SQLException {
    statement = conn.prepareStatement(Queries.SAVE_CONNECT);
    statement.setString(1, dbConnectInfo.getName());
    statement.setString(2, dbConnectInfo.getType());
    statement.setString(3, dbConnectInfo.getHost());
    statement.setString(4, dbConnectInfo.getUsername());
    statement.setString(5, dbConnectInfo.getPassword());
    statement.executeUpdate();
  }
}